
def chalk_with_dot_settings():
    '''
    This function tells you what settings are needed and in what order for this stimulus.
    Inputs:
        None
    Returns:
        settings        : A list of tupples.  In each tupple is
                            (setting_name, setting_description, default_value).
                          The list is of length num_settings + 1, so that the final
                             value in the list is True/False wether or not the stimulus
                             can be triggered via the parallel port or not.
    '''
    settings = []
    settings.append( ('shade',
                     '1.0 for black-dot, -1.0 for white-dot.',
                     1.0 ))
    settings.append( ('win_size',
                     'The dimensions of the stimulus delivery window. (pixels) [list]',
                     [1440,900] ))
    settings.append(False) # this stimulus can be triggered
    return settings
    
def chalk_with_dot(shade, win_size, window=None, eye_cup=None, rf=None, eye_cup_opacity=0.13, preview=True):
    '''
    Allow the user to move the mouse to guide a dot around the screen.  Left click
         will denote hotspots, while right clicking will make the dot appear.
    Inputs:
        shade           : 1.0 for black-bar, -1.0 for white-bar
        win_size        : the size of the window in pixels
        --- kwargs --
        window          : a psychopy.visual Window object, if not passed it will be constructed.
                        :    if passed it will not be closed (a blank screen will be drawn)
        eye_cup         : an Eye_cup object, so we can see what the eye_cup looks like.
        rf              : irrelevant, just there for interface consistancy
        preview         : If True, no image is saved.
    Returns:
        None
    '''
    from psychopy import event, core
    from psychopy import visual
    from psychopy.visual import Window
    import scipy
    from helper_codes.Eye_cup import Eye_cup
    import time

    # -------------------------------------------------
    # -- Create the window and stimuli
    # -------------------------------------------------
    if window == None: # no window object was passed.
        myWin = Window(win_size, allowGUI=False, fullscr=False, pos=(0,-900), rgb=1.0*shade)
    else:
        myWin = window # the passed window object
    
    myMouse = event.Mouse(win=myWin)
    message = visual.TextStim(myWin, pos=(0.0,0.9), alignHoriz = 'center' ,height = 0.03, 
                  text = 'left click:denote "hotspot"\nright click: show spot\nEsc to quit.',
                  rgb = -1.0*shade )

    if eye_cup == None:
        print "No eye cup object passed, reading eye coordinates from file."
        eye_cup = Eye_cup.from_eye_cup_file()

    eye_cup.prep_for_drawing( myWin, shade=shade, opacity=eye_cup_opacity)

    dot_size = 0.05
    aspect_ratio = win_size[0]/float(win_size[1])
    dot = visual.PatchStim(myWin, pos=(0.0,0.0),tex = scipy.ones((8,8))*-shade,       
                mask='circle', size = (dot_size,dot_size*aspect_ratio), interpolate=True)

    hotspot_set = set()
    keep_looping = True
    while keep_looping: #continue until keypress
        # always draw the eye_cup first.
        eye_cup.draw()

        #handle key presses each frame
        for key in event.getKeys():
            if key in ['escape','q']:
                keep_looping = False
                
        #get mouse events
        mouse_X,mouse_Y = myMouse.getPos()
        #set_X_pos = (  mouse_X/float(win_size[0])  )*2.0 - 1.0
        #set_Y_pos = (  -mouse_Y/float(win_size[1])  )*2.0 - 1.0
        set_X_pos = mouse_X
        set_Y_pos = mouse_Y
        dot.setPos((set_X_pos,set_Y_pos))
        mouse1, mouse2, mouse3 = myMouse.getPressed()
        if mouse1:
            hotspot_set.add((set_X_pos, set_Y_pos, dot_size))
        if mouse3:
            #do the drawing
            dot.draw()
            
        #Handle the wheel(s):
        # Y is the normal mouse wheel, but some (e.g. mighty mouse) have an x as well
        wheel_dX, wheel_dY = myMouse.getWheelRel()
        dot_size = dot_size + 0.01*wheel_dY
        dot.setSize((dot_size,dot_size*aspect_ratio))
        
        event.clearEvents()#get rid of other, unprocessed events
        
        message.draw()
        myWin.flip()#redraw the buffer
        time.sleep(0.01)

    hotspots = list(hotspot_set)
    dots = [visual.PatchStim(myWin, pos=(posx,posy),tex = scipy.ones((8,8))*-shade,
                mask='circle', opacity=0.15,interpolate=True, size = (size,size*aspect_ratio)) \
                for posx,posy,size in hotspots ]
    
    eye_cup.draw()
    for dot in dots:
        dot.draw()
    myWin.flip()
    myWin.getMovieFrame()
    if not preview:
        filename = 'chalk_with_dot--shade %d.jpg' % shade
        myWin.saveMovieFrames(filename)

    if window == None: # no window object was passed.
        myWin.close()
    else: # we don't want to close the window if it was passed in.
        white_splotch = visual.PatchStim(myWin, tex=scipy.ones((8,8)),
                                         size=(10000,10000) )
        white_splotch.draw()
        myWin.flip()
        white_splotch.draw()
        myWin.flip() # this should leave us with a blank white screen.

    # make sure we delete the dot texture when we're done with it.
    dot.clearTexture()

    return None


if __name__ == '__main__':

    win_size = (1440,900)
    shade = 1.0  # 1.0 for white, -1.0 for black

    from psychopy.visual import Window
    import time

    # testing if passing a window works as expected... it should work normally except
    #   that at the end when the user hits escape the screen shows the hidden rf that was chalked
    #   for only one frame then a white screen for three seconds.
    window = Window(win_size, allowGUI=False, fullscr=False, pos=(0,-900), rgb=1.0*shade)
    chalk_with_dot(shade, win_size, window=window)
    print "waiting 3 seconds."
    time.sleep(3.0)
    window.close()

